package org.wii.auth.handlers;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.exception.BackResultException;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.exception.StopMatchException;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.stp.SaLoginConfig;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.strategy.SaStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.RouteMatcher;
import org.springframework.web.method.HandlerMethod;
import org.wii.auth.annotation.NonAuth;
import org.wii.base.context.UserInfoContextHolder;
import org.wii.base.exception.IWiiException;
import org.wii.base.exception.constant.UserRequestBaseExceptionEnum;
import org.wii.base.user.UserBaseInfo;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * 授权拦截器
 * @author tanghong on 2022/12/26
 */
@Slf4j
public class AuthHandlerInterceptor extends SaInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        try {
            if(isAnnotation && handler instanceof HandlerMethod) {
                Method method = ((HandlerMethod) handler).getMethod();
                if(SaStrategy.me.isAnnotationPresent.apply(method, SaIgnore.class) || SaStrategy.me.isAnnotationPresent.apply(method, NonAuth.class)) {
                    return true;
                }
                // 注解校验
                SaStrategy.me.checkMethodAnnotation.accept(method);
            }
            // Auth 校验
            try {
                StpUtil.checkLogin();
            } catch (Exception e){
                throw new IWiiException(UserRequestBaseExceptionEnum.NOT_LOGIN);
            }
            Object userId = StpUtil.getExtra("userId");
            if (Objects.nonNull(userId)){
                // 添加用户上下文信息
                UserInfoContextHolder.setUserInfo(UserBaseInfo.build((String) userId, (String) StpUtil.getLoginId()));
            }
        } catch (StopMatchException e) {
            // 停止匹配，进入Controller 
        } catch (BackResultException e) {
            // 停止匹配，向前端输出结果 
            if(response.getContentType() == null) {
                response.setContentType("text/plain; charset=utf-8");
            }
            response.getWriter().print(e.getMessage());
            return false;
        }
        // 通过验证
        return true;
    }

    public static void main(String[] args) {
        AntPathMatcher pathMatcher = new AntPathMatcher();
        System.out.println(pathMatcher.match("/user/api/v1/client/**", "/user/api/v1/client/info"));
    }
}
